﻿using System;
using System. Linq;
using System. Net;
using System. Windows;
using System. Windows. Controls;
using System. Windows. Data;
using System. Windows. Input;
using System. Xml. Linq;
using Microsoft. Phone. Controls;
using Microsoft. Phone. Shell;
using NextApp. WP7. AppConfig;
using NextApp. WP7. Models;
using NextApp. WP7. UnionLib;
using System. Windows. Media;
using NextApp. WP7. Util;
using WP7_ControlsLib. Controls;
using System. Collections;
using System. Collections. Generic;
using System. Collections. ObjectModel;
using System. Windows. Threading;
using NextApp. WP7. Cache. NextApp;

namespace NextApp. WP7. View. Controls
{
    public partial class PostsList : UserControl
    {
        #region Initialize
        public PostsList( )
        {
            InitializeComponent( );
            this. Loaded += new RoutedEventHandler(PostsList_Loaded);
			this. postsBinding. Add(this. loadNextTip); 
			this. list_Posts. ItemsSource = this. postsBinding;
			this. loadNextTip. Click += (s, e) =>
				{
					this. LoadNextPosts( );
				};
			//滚动检测
			this. list_Posts. LayoutUpdated += new EventHandler(list_Posts_LayoutUpdated);
        }

		private LoadNextTip loadNextTip = new LoadNextTip
		{
			Text = "正在刷新",
			HorizontalAlignment = HorizontalAlignment. Center,
			HorizontalContentAlignment = HorizontalAlignment. Center,
			Width = 480,
			MinWidth = 480,
			Height = 100,
			MinHeight = 100,
		};

        private const int fetchCount = 5;
        private int fromPost = 0;
        public int catalogID { get; set; }
        public bool IsHostByMainPage { get; set; }
        private bool IsLoadingData { get; set; }
		private ObservableCollection<object> postsBinding = new ObservableCollection<object>( );
		private ScrollViewer listBox_ScrollViewer;
		private double lastListBoxScrollableVerticalOffset = 0;
		private void list_Posts_LayoutUpdated(object sender, EventArgs e)
		{
			if ( this. listBox_ScrollViewer != null )
			{
				//是否往下滑动
				bool isGoingDown = this. listBox_ScrollViewer. VerticalOffset > lastListBoxScrollableVerticalOffset;
				this. lastListBoxScrollableVerticalOffset = this. listBox_ScrollViewer. VerticalOffset;
				//是否在监控的最底部区域
				bool isInReloadRegion = this. listBox_ScrollViewer. VerticalOffset >= ( this. listBox_ScrollViewer. ScrollableHeight - Config. ScrollBarOffset );
				if ( isInReloadRegion &&
					isGoingDown  )
				{
					this. LoadNextPosts( );
				}
			}
			else
			{
				this. listBox_ScrollViewer = ControlHelper. FindChildOfType<ScrollViewer>(this. list_Posts);
			}
		}
        public void Reload( bool isInitialize = true, int from = -1, bool isClearItemSource = false )
        {
            //是否需要清空 ListBox 的缓存
            if ( isClearItemSource )
            {
				this. postsBinding. Clear( );
				this. postsBinding. Add(this. loadNextTip);
				this. loadNextTip. Text = "正在刷新";
            }
            //判断是否可从缓存中获取数据
            this. CheckIsCached( );
            //开始获取
			WebClient client = Util. Tool. GetWebClient;
            client. DownloadStringCompleted += (s, e1) =>
			{
				CacheNextApp. Instance. MinusBandwidthCost(new BandwidthCostNextApp { cost = BandwidthCostNextApp. Post_List });
				#region 错误处理
				if ( e1. Error != null )
                {
                    MessageBox. Show("获取此分类下的文章列表失败", "网络错误", MessageBoxButton. OK);
                    return;
				}
				#endregion

				#region 获取到了数据
				XElement x;
				try
				{
					x = XElement. Parse(e1. Result);
				}
				catch ( Exception )
				{
					return;
				}
                PostList postList = new PostList
                {
                    catalog = x. Element("catalog"). Value. ToInt32( ),
                    postCount = x. Element("postCount"). Value. ToInt32( ),
                    posts = x. Element("posts") == null ?
                        null :
                        x. Element("posts"). Elements("post"). Select(
                        p => new Post
                        {
                            id = p. Element("id"). Value. ToInt32( ),
                            title = p. Element("title"). Value,
                            outline = p. Element("outline"). Value,
                            commentCount = p. Element("commentCount"). Value. ToInt32( ),
                            authorId = p. Element("authorId"). Value. ToInt32( ),
                            author = p. Element("author"). Value,
                            catalog = p. Element("catalog"). Value. Split(','). Select(c => c. ToInt32( )). ToArray( ),
                            pubDate = p. Element("pubDate"). Value,
                        }
                    ). ToArray( ),
                };
                #endregion

                #region 如果获取到了新数据
                if ( postList. posts != null )
				{
					this. loadNextTip. Text = "更多 . . .";
					//获取已有的文章的 id 集合
					int[ ] postIDS = this. postsBinding. Select(p =>
						{
							Post tempP = p as Post;
							return tempP == null ? -1 : tempP. id;
						}). ToArray( );
					//然后插入数据  需要判断重复性
					postList. posts. ForAll
						(( p =>
						{
							if ( postIDS. Contains(p. id) == false )
							{
								this. postsBinding. Insert(this. postsBinding. Count - 1, p);
							}
						} ));
                    //将没有文章的提示关闭显示
                    this. tblock_NoPostsTip. Visibility = System. Windows. Visibility. Collapsed; 
                    //执行后台搜索
                    this. NotifyStartToPollNewBlogs( );
                }
                #endregion

                #region 如果这次没有获取新数据
                else
                {
					if ( isInitialize && this. list_Posts. Items. Count <= 0 )
					{
						this. tblock_NoPostsTip. Text = "没有文章";
						this. tblock_NoPostsTip. Visibility = System. Windows. Visibility. Visible;
					}
					else
					{
						this. loadNextTip. Text = "已经没有最新文章";
					}
                }
                #endregion
                //通知 MainPage
                this. IsDisplayProgressBar(false);
            };
			#region 异步加载
			if ( NextAppSingleton.Instance.url_post_list.IsNotNullOrWhitespace() )
            {
                string url = Config. Instance. GetApi(string. Format("{0}&catalog={1}&fromPost={2}&fetchCount={3}&guid={4}",
                                                                                NextAppSingleton. Instance. url_post_list,
                                                                                this. catalogID,
                                                                                from < 0 ? this. fromPost : from,
                                                                                fetchCount,
                                                                                Guid. NewGuid( )));
				CacheNextApp. Instance. AddBandwidthCost(new BandwidthCostNextApp { cost = BandwidthCostNextApp. Post_List });
                client. DownloadStringAsync(new Uri(url, UriKind. Absolute));
                
                //展示进度条
                this. IsDisplayProgressBar(true);
			}
			#endregion
		}
        private void IsDisplayProgressBar(bool visible)
        {
            if ( this. IsHostByMainPage )
            {
                EventSingleton. Instance. RaiseOnMainPageLoading(visible);
            }
            else
            {
                this. ProgressIndicatorIsVisible = visible;
            }
            //加载指示器
            this. IsLoadingData = visible;
        }
        private void CheckIsCached( )
        {
        }
		private void LoadNextPosts( )
		{
			if ( this. IsLoadingData )
			{
				System. Diagnostics. Debug. WriteLine("文章刷新中 无法重新获取");
				return;
			}
			if ( this. postsBinding. IsNotNullOrEmpty( ) && this. postsBinding. Count >= 2 )
			{
				Post lastPost = this. postsBinding[ this. postsBinding. Count - 2 ] as Post;
				if ( lastPost != null )
				{
					this. fromPost = lastPost. id;
					this. Reload(false);
				}
			}
		}
        #endregion

        #region 点击某篇文章
        private void list_Posts_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Post p = this. list_Posts. SelectedItem as Post;
            this. list_Posts. SelectedItem = null;
            //跳转
            if ( p != null )
            {
                ( Application. Current. RootVisual as PhoneApplicationFrame ). Navigate(new Uri(string. Format("/View/PostDetail.xaml?post={0}", p. id), UriKind. Relative));
            }
        }
        #endregion

        #region 进度条设置
        void PostsList_Loaded(object sender, RoutedEventArgs e)
        {
            SystemTray. ProgressIndicator = new ProgressIndicator( );
            SystemTray. ProgressIndicator. Text = "加载中";

            Binding bindingData;
            bindingData = new Binding("ProgressIndicatorIsVisible");
            bindingData. Source = this;
            BindingOperations. SetBinding(SystemTray. ProgressIndicator, ProgressIndicator. IsVisibleProperty, bindingData);
            BindingOperations. SetBinding(SystemTray. ProgressIndicator, ProgressIndicator. IsIndeterminateProperty, bindingData);
        }
        public static readonly DependencyProperty ProgressIndicatorIsVisibleProperty =
            DependencyProperty. Register("ProgressIndicatorIsVisible",
            typeof(bool),
            typeof(PostsList),
            new PropertyMetadata(false));
        public bool ProgressIndicatorIsVisible
        {
            get { return ( bool )GetValue(ProgressIndicatorIsVisibleProperty); }
            set { SetValue(ProgressIndicatorIsVisibleProperty, value); }
        }
        #endregion

        #region 将某篇文章订到桌面上
        private void menuItem_PostPinToStart_Click(object sender, RoutedEventArgs e)
        {
            Post p = ( sender as MenuItem ). DataContext as Post;
            if ( p != null )
            {
                Util. Tool. CreateShellTile(p);
            }
        }
        #endregion

        #region 获取文章列表后通知开始轮询后台搜索
        private void NotifyStartToPollNewBlogs( )
        {
            if ( this.catalogID == 0 )
            {
                Post lastP = this. list_Posts. Items. LastOrDefault( ) as Post;
                if ( lastP != null )
                {
                    EventSingleton. Instance. RaiseOnGetPosts(new RenewBlogs
                    {
                        Duration = Config. Instance. TimeSpan_Polling,
                        LastPostID = lastP. id,
                        title = Config. Instance. blog_title,
                        Uri = Config. Instance. GetApi(string. Format("{0}&catalog=0&fromPost={1}&fetchCount=99", NextAppSingleton. Instance. url_post_list, lastP. id)),
                        UserAgent = Config. Instance. Http_User_Agent,
                    });
                }
            }
        }
        #endregion
	}
}
